use std::collections::HashSet;

use rand::Rng;

/** # 随机整数
随机生成1到100之间的整数1000个。

- 统计每个数出现的次数
- 编写方法求出其中出现的最大值（方法头如下）：
```java
public static int min(int[] array);
```
- 使用下面方法头编写方法，消除其中的重复值:
```java
public static int[] eliminatedDuplicate(int[] lst);
``` */
pub fn random_integer() {
    // 生成 1000 个 1~100 的随机数
    let randoms: Vec<u8> = init_random();
    assert_eq!(randoms.len(), 1000);

    // 统计每个数字出现的次数
    let repeat_count = repeat_count(&randoms);
    println!("\n数组中重复出现的数字统计：{:?}", repeat_count);

    // 找出最大值
    println!("\n最大值是{}", min(&randoms));

    // 消除重复值
    let eliminated_duplicate = eliminated_duplicate(&randoms);
    println!("\n消除重复值后的数组：{:?}", eliminated_duplicate);
}

/** ## 随机数组
- 利用while循环生成 1000 个 1~100 的整数
*/
fn init_random() -> Vec<u8> {
    let mut randoms: Vec<u8> = vec![];
    while randoms.len() < 1000 {
        randoms.push(rand::rng().random_range(1..=100));
    }
    randoms
}

/** ## 统计每个数字出现的次数 */
fn repeat_count(array: &Vec<u8>) -> Vec<Count> {
    // 一个类型为 Count 的数组
    // 用于记录每个数字出现的个数
    let mut counts: Vec<Count> = vec![];

    for item in array {
        let mut is_not_repeat = true;
        // 循环 counts 数组，直到发现重复的数字后计数并结束循环
        for count in &mut counts {
            if item == &count.value {
                count.add();
                is_not_repeat = !is_not_repeat;
                break;
            }
        }

        // 如果最终都没发现重复值，则为 counts 数组单独添加单间数字的记录
        if is_not_repeat {
            counts.push(Count {
                value: *item,
                count: 1,
            });
        }
    }

    counts
}

/** 找出最大值 */
fn min(array: &Vec<u8>) -> u8 {
    let mut max_value = 0;

    // 循环数组，发现比 max_value 大的值时，就将该值重新赋给 max_value
    for value in array {
        if value > &max_value {
            max_value = *value
        }
    }
    max_value
}

/** ## 消除重复值 */
fn eliminated_duplicate(lst: &Vec<u8>) -> Vec<u8> {
    lst.clone()
        .into_iter()
        .collect::<HashSet<_>>()
        .into_iter()
        .collect()
}

/** 计数 */
#[derive(Debug)]
struct Count {
    value: u8,
    count: u8,
}

impl Count {
    fn add(&mut self) {
        self.count += 1;
    }
}
